package com.hsd.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hsd.pojo.History;
import com.hsd.pojo.Result;
import com.hsd.service.HistoryService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
/*
 * @ Author zyt
 * @ Create 2025/4/15
 * @ Version 2.0
 */


@Aspect
@Component
@Slf4j
/*
  准备使用AOP切面来实现请求的记录，不使用注解来标记了，直接对包里的所有方法切面解析
 */
public class HistoryAspect {

    @Autowired
    private HistoryService historyService;

    // 定义切入点，匹配所有 com.hsd.controller 包下的方法
    @Pointcut("execution(* com.hsd.controller.*.*(..))")
    public void logRequestMethods() {
    }

    // 环绕通知，拦截目标方法
    @Around("logRequestMethods()")
    public Object logRequest(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取 HttpServletRequest
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

        // 获取请求路径
        String requestPath = request.getRequestURI();

        // 获取方法参数
        Object[] args = joinPoint.getArgs();

        // 执行目标方法，并获取返回值
        Object result = joinPoint.proceed();

        // 获取计算结果
        String data = ((Result) result).getData().toString();

        // 格式化计算记录
        String historyInfo = formatHistoryInfo(requestPath, args, data);

        // 创建History对象
        History history = new History();
        history.setHistory(historyInfo);
        history.setCreateTime(new Date());
        history.setUpdateTime(new Date());
        history.setIsDelete(0);

        // 插入数据库
        historyService.save(history);

        // 返回方法执行结果
        return result;
    }

    // 格式化计算记录
    private String formatHistoryInfo(String requestPath, Object[] args, Object result) {
        return switch (requestPath) {
            case "/calculate/ffo/add" -> {
                Map<String, Number> addParams = (Map<String, Number>) args[0];
                yield String.format("%s + %s = %s", addParams.get("num1"), addParams.get("num2"), result);
            }
            case "/calculate/ffo/subtract" -> {
                Map<String, Number> subtractParams = (Map<String, Number>) args[0];
                yield String.format("%s - %s = %s", subtractParams.get("num1"), subtractParams.get("num2"), result);
            }
            case "/calculate/ffo/multiply" -> {
                Map<String, Number> multiplyParams = (Map<String, Number>) args[0];
                yield String.format("%s * %s = %s", multiplyParams.get("num1"), multiplyParams.get("num2"), result);
            }
            case "/calculate/ffo/division" -> {
                Map<String, Number> divisionParams = (Map<String, Number>) args[0];
                yield String.format("%s / %s = %s", divisionParams.get("num1"), divisionParams.get("num2"), result);
            }
            case "/calculate/tf/sin" -> {
                Map<String, Number> sinParams = (Map<String, Number>) args[0];
                yield String.format("sin(%s) = %s", sinParams.get("num"), result);
            }
            case "/calculate/tf/cos" -> {
                Map<String, Number> cosParams = (Map<String, Number>) args[0];
                yield String.format("cos(%s) = %s", cosParams.get("num"), result);
            }
            case "/calculate/tf/tan" -> {
                Map<String, Number> tanParams = (Map<String, Number>) args[0];
                yield String.format("tan(%s) = %s", tanParams.get("num"), result);
            }
            case "/calculate/tsp/nthp" -> {
                Map<String, Number> nthpParams = (Map<String, Number>) args[0];
                yield String.format("%s ^ %s = %s", nthpParams.get("num"), nthpParams.get("n"), result);
            }
            case "/calculate/tsp/knthp" -> {
                Map<String, Number> knthpParams = (Map<String, Number>) args[0];
                yield String.format("√%s = %s", knthpParams.get("num"), result);
            }
            case "/calculate/radix/totwo" -> {
                Map<String, Number> totwoParams = (Map<String, Number>) args[0];
                yield String.format("%s (十进制) = %s (二进制)", totwoParams.get("num"), result);
            }
            case "/calculate/radix/toten" -> {
                Map<String, String> totenParams = (Map<String, String>) args[0];
                yield String.format("%s (二进制) = %s (十进制)", totenParams.get("num"), result);
            }
            default -> "Unknown operation";
        };
    }
}
